package NG::Sys::Cached::DBReference;
use strict;
use warnings;
use utf8;

use JSON::XS;

use NG::Sys::Cached::Reference;
our @ISA = qw(NG::Sys::Cached::Reference);

sub init {
	my $self = shift;
	$self->SUPER::init;
	unless($self->{table}){
		die "need table\n";
	}
	unless($self->{dbh}){
		die "need dbh\n";
	}
	$self->{sth}{read} = $self->{dbh}->prepare("select * from `".$self->{table}."`");
}
sub _read_source {
	my $self = shift;
	my $sth = $self->{sth}{read};
	$sth->execute;
	return $sth->fetchall_arrayref({});
}
sub save_row {
	my $self = shift;
	my $row = shift;
	if($self->{blobs}){
		for(@{$self->{blobs}}){
			if(defined $row->{$_}){
				$row->{$_} = encode_json(normalize_blob($row->{$_}));
			}
		}
	}
	$self->{app}->logger->info(Data::Dumper::Dumper($row));
	return $self->{dbh}->Replace($self->{table} => $row);
}
sub update_row {
	my $self = shift;
	my $row = shift;
	if($self->{blobs}){
		for(@{$self->{blobs}}){
			if(exists $row->{$_}){
				if(defined $row->{$_}){
					$row->{$_} = encode_json(normalize_blob($row->{$_}));
				}
			}
		}
	}
	$self->{app}->logger->info(Data::Dumper::Dumper($row));
	return $self->{dbh}->Update($self->{table}, [$self->{pkey}], $row);
}
sub remove_row {
	my $self = shift;
	my $row_id = shift;
	$self->{dbh}->Delete($self->{table} => {$self->{pkey} => $row_id});
}
sub max {
	return $_[0] < $_[1] ? $_[1] : $_[0];
}
sub normalize_blob {
	my $blob = shift;
	my $max = 0;
	my @k = keys %$blob;
	for my $k(@k){
		if($blob->{$k} && ref $blob->{$k} eq "ARRAY"){
			$max = max($max,scalar @{$blob->{$k}});
		}
	}
	unless($max){
		return $blob;
	}
	my @res;
	for(my $i = 0; $i < $max; $i++){
		my %r;
		for my $k(@k){
			$r{$k} = $blob->{$k}[$i];
		}
		push @res,\%r;
	}
	return \@res;
}

1;
